import * as Cesium from 'cesium'
import {useHawkEye3DMap} from '../Material/HawkEye3DMap'
import type { useEarthGroup } from './EarthViewerGroup';
import { SaveTypeFileByContent } from '../UtilFn';

export class useDrawLayerMirror{

    viewer:Cesium.Viewer;

    // 鹰眼地图的对象
    hawkEyeMap:useHawkEye3DMap;
    // 多彩地球的图形基元对象
    primitiveObj:any = null;
    constructor(view:Cesium.Viewer){
        if(!view){
            throw new Error("请传入地图的图层")
        }

        this.viewer = view;
        return this;
    }
    useMain(type:string,param?:unknown){
        let _url = param || ''
        
        switch(type){
            case "white_mirror":
                this.setEarthOSMHighLow(_url as string);
                break;
            case "dark_mirror":
                this.setEarthOSMDarkLow(_url as string);
                break;
            case "default_mirror":
                this.setEarthOSMDefault(_url as string)
                break;
            case "compass":
                this.set3DMapEye()
                break;
            case "colorful":
                this.setColorFulEarth()
                break;
            case "FramesPerSecond":
                this.FramesPerSecond()
                break;
            case "HeatMap":
                this.AddHeatMap(_url as string)
                break;
            case "KMLData":
                this.exportKMLData(_url as useEarthGroup);
                break;
            default:
                console.log("未找到此类型");
                break;
        }
    }
    /**
     * 修改地图为默认底图
     * @param url 
     */
    setEarthOSMDefault(url:string){
        // 因为图层原因，cesium只会使用最后一个加入的图层，因此将后加入的图层全部删除，只留下第一个即可
        while(this.viewer.imageryLayers.length>1){
            this.viewer.imageryLayers.remove(this.viewer.imageryLayers.get(1))
        }
    }
    /**
     * 修改地图底图
     * 加载OSM在线地图（标准风格）（白色风格）
     * @param url 
     */
    setEarthOSMHighLow = (url:string)=>{
        this.viewer.imageryLayers.addImageryProvider(
            new Cesium.UrlTemplateImageryProvider({
                url: url || 'https://tile-{s}.openstreetmap.fr/hot/{z}/{x}/{y}.png',
                subdomains: ["a", "b", "c", "d"],
            })
        )
    }
    /**
     * 修改地图底图
     * 加载OSM在线地图（黑色风格）
     */
    setEarthOSMDarkLow = (url:string)=>{
       this.viewer.imageryLayers.addImageryProvider(
           new Cesium.UrlTemplateImageryProvider({
               url: url || "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
               subdomains: ["a", "b", "c", "d"],
           })
       );
     }
     /**
      * 添加鹰眼
      * @returns 
      */
     set3DMapEye(){
            // 鹰眼地图初始化
        if(this.hawkEyeMap){
            let div=this.hawkEyeMap.hawkEyeDiv;
            let b = getComputedStyle(div,null).display;
            let show = b == "block"?"none":"block";
            div.style.display = show
            return;
        }
        this.hawkEyeMap = new useHawkEye3DMap(this.viewer);
        this.hawkEyeMap._init();
     }
     /**
      * 创建多彩的地球
      */
     setColorFulEarth(){
        
        if(this.primitiveObj){
            // 如果多彩地球一被创建，则直接控制显隐即可，无需重新创建浪费性能
            let f = this.primitiveObj.show;
            this.primitiveObj.show = !f;
            return;
        }
        let instance = [];
        for(let lon=-180.0;lon<180.0;lon+=5){
          for(let lat=-90.0;lat<90.0;lat+=5){
            let geom = new Cesium.GeometryInstance({
              geometry:new Cesium.RectangleGeometry({
                rectangle:Cesium.Rectangle.fromDegrees(lon,lat,lon+5,lat+5)
              }),
              attributes:{
                color:Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha:0.6}))
              }
            })
            instance.push(geom);
          }
        }
        this.primitiveObj = new Cesium.Primitive({
            show:true,
            geometryInstances:instance,
            appearance:new Cesium.PerInstanceColorAppearance()
          });
        this.viewer.scene.primitives.add(this.primitiveObj)
     }
     /**
      * 显示帧率
      */
    FramesPerSecond = ()=>{
        let flag = !this.viewer.scene.debugShowFramesPerSecond
        this.viewer.scene.debugShowFramesPerSecond = flag;
    }
    /**
     * 存放所有热力图的集合
     */
    HeatMapObj = new Map();
    /**
     * 绘制热力图
     * @description 此热力图其实就是让后端给传来一张图，前端将图添加到三维球上即可
     * @param url 
     * @param index 可选 图层的索引
     * @param twidth 可选 图层的宽
     * @param theight 可选 图层的高
     * @param isDestroy 可选 删除图层时是否销毁这些图层
     * @returns 返回被删除或添加的图层对象
     */
    AddHeatMap(url:string,index?:number,twidth?:number,theight?:number,isDestroy:boolean=true){
        if(this.HeatMapObj.get(url)){
            let layer = this.HeatMapObj.get(url);
            this.viewer.imageryLayers.remove(layer,isDestroy)
            return layer;
        }else{
            let layer = this.viewer.imageryLayers.addImageryProvider(new Cesium.SingleTileImageryProvider({
                url:url,
                tileWidth: twidth || 100,
                tileHeight: theight || 100
            }),index||void 0)
            this.HeatMapObj.set(url,layer)
            return layer;
        }
    }
    /**
     * 导出成kml对象
     * @param viewGroup 组对象
     */
    exportKMLData(viewGroup:useEarthGroup,modelCallback?:Function|null,CallBack?:Function){
        if(!viewGroup){
            throw new Error("请传入组对象")
        }
        Cesium.exportKml({
            entities: viewGroup.getCurrentEntitys(),
            modelCallback
        }).then((res:any)=>{
            let prefixKml = '<?xml version="1.0" encoding="UTF-8"?>'
            CallBack instanceof Function ? CallBack(res,prefixKml) : SaveTypeFileByContent(prefixKml + res.kml,"task.kml","application/xml")
        })
    }
    /**
     * 加载KML文件
     * @param content 要加载的KML文件 Blob | string 
     * @param options 
     * @returns true | error
     */
    loadKmlData(content: string | Blob,options?:object){
        return new Promise(async (resolve,reject)=>{
            let _options = {
                camera: this.viewer.scene.camera,
                canvas: this.viewer.scene.canvas,
                ...options
            }
            try{
                let res = await Cesium.KmlDataSource.load(content,_options);
                this.viewer.dataSources.add(res);
                resolve(true)
            }catch(e){
                reject(e)
            }
        })
    }
}